package com.xuxueli.applyModules.utils;
import com.alibaba.fastjson.JSONObject;
import com.xuxueli.applyModules.entity.Domain;
import com.xuxueli.applyModules.entity.TestDate;
import com.xuxueli.applyModules.entity.User;
import com.xuxueli.applyModules.exception.ErrorException;
import com.xuxueli.applyModules.utils.exporttables.TestDoc;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.datasource.DataSourceException;
import java.io.*;
import java.net.URI;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 通用生成/验证签名及时间戳和获取端口号类
 */
public class TestData {

    public static void main(String[] args) {
        trstMethod();
        //随机生成9位hashcode
        Long valueOf = Long.valueOf(UUID.randomUUID().toString().hashCode());
        valueOf = valueOf > 0 ? valueOf : -1 * valueOf;
        String serviceCode = "gaia" + valueOf;
        System.out.println(serviceCode);
        //LocalDateTime和ChronoUnit为1.8新增
        LocalDateTime midnight = LocalDateTime.now().plusDays(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
        long millSeconds = ChronoUnit.MILLIS.between(LocalDateTime.now(),midnight);
        long seconds = ChronoUnit.SECONDS.between(LocalDateTime.now(), midnight);
        System.out.println("当天剩余毫秒：" + millSeconds);
        System.out.println("当天剩余秒：" + seconds);
        String serviceName = "plugin-oracle-12-datetavlewsdkcskTable";
        String[] services = serviceName.split("-");
        String dataBaseType = "";
        if (services.length == 4) {
            dataBaseType = dataBaseType + services[1] + "." + services[2] + "." + services[3];
        } else if (services.length == 3) {
            dataBaseType = dataBaseType + services[1] + "." + services[2];
        }else {
            dataBaseType = dataBaseType + services[1];
        }
        System.out.println(dataBaseType);
        System.out.println(serviceName);
        String values = "plugin-" + dataBaseType.replace(".", "-");
        System.out.println(values);
        TestDate testDate = new TestDate();
        String apiUrl = "http://api-setor.com/getuserInfo；";
        testDate.setValue(apiUrl);
        System.out.println("原始url："+testDate.getValue());
        int random = new Random().nextInt(2);
        testDate.setValue(testDate.getValue().replace("；",";"));
        System.out.println("最终url："+testDate.getValue());
        System.out.println("获取第一个url："+testDate.getValue().split(";")[0]);
        System.out.println("随机数："+random);
        String apiUrls = "http://api-setor.com/getuserInfo";
        apiUrls = apiUrls.replace("；",";");
        List<String> stringList = Arrays.asList(apiUrls.split(";"));
        Boolean existFlag = false;
        int randoms = new Random().nextInt(stringList.size());
        System.out.println("随机访问url："+stringList.get(randoms));
        if(stringList.size() > 1){
            for (int i = 0; i < stringList.size()-1; i++) {
                String cunrrent = stringList.get(i);
                String next = stringList.get(i+1);
                if((cunrrent.startsWith("http://") && next.startsWith("http://")) ||
                        (cunrrent.startsWith("https://") && next.startsWith("https://"))){
                    System.out.println("数据格式一致");
                }else{
                    System.out.println("数据格式不一致");
                    existFlag = true;
                }
            }
        }else{
            if(stringList.get(0).startsWith("http://") || stringList.get(0).startsWith("https://")){
                System.out.println("数据格式一致");
            }else{
                System.out.println("数据格式有误");
                existFlag = true;
            }
        }
        if(existFlag){
            System.out.println("数据格式存在不一致情况");
        }
        long currentTimeMillis = System.currentTimeMillis();
        System.out.println(currentTimeMillis);
        Calendar calendar = Calendar.getInstance();
        long testTimeMillis = 1669188297000L;
        calendar.setTimeInMillis(testTimeMillis);
        Date time = calendar.getTime();
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String format = dateFormat.format(time);
        System.out.println("当前时间："+format);
        System.out.println("时间戳："+checkTimeStampInPeriod(testTimeMillis));
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("code", RandomStringUtils.random(16,true,true));
        byte[] toByteArray = toByteArray(parameters);
        System.out.println(toByteArray);
        Object objectToByte = toObjectType(toByteArray);
        System.out.println(objectToByte);
        String exportDoc = TestDoc.exportDoc("D:\\data\\你好.doc");
        byte[] toByteArrays = toByteArray(exportDoc);
        System.out.println(toByteArrays);
        Object objectToBytes = toObjectType(toByteArrays);
        System.out.println(objectToBytes);
        if(null!=objectToByte){
            JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(objectToByte));
            System.out.println(jsonObject);
        }
        String signature = createSignature("testkey", parameters, currentTimeMillis);
        System.out.println("签名："+checkSignature("testkey",parameters,currentTimeMillis,signature));
        String scheme = "";
        int servicePorts = 0;
        for (String url:stringList){
            if(StringUtils.isBlank(url) || "null".equals(url)){
                continue;
            }
            String targetUrl = "";
            int ports = 0;
            if(StringUtils.containsIgnoreCase(url,"http://") || StringUtils.containsIgnoreCase(url,"https://")){
                URI uri = URI.create(url);
                ports = uri.getPort();
                String path = uri.getPath();
                System.out.println(path);
                scheme = uri.getScheme();
                if("http".equals(scheme)){
                    if (ports < 0) {
                        ports = 80;
                    }
                    servicePorts = 80;
                }else if("https".equals(scheme)){
                    if (ports < 0) {
                        ports = 443;
                    }
                    servicePorts = 443;
                }
                targetUrl = uri.getHost()+":"+ports;
                System.out.println("网络协议："+scheme+"\nIP:："+uri.getHost()+"\n端口号："+ports+"\n服务端口号："+servicePorts);
                System.out.println(String.format("发布target地址：%s，服务协议：%s以及端口号：%s",targetUrl,scheme,servicePorts));
            }else{
                System.out.println("无效IP");
            }
        }
        System.out.println("***********************************************");
        String url = "https://api-setor.com/sdfs/asfas?code=2312";
        //String url = "https://10.0.40.122:";
//        String scheme = "";
//        String targetUrl = "";
//        int ports = 0;
//        int servicePorts = 0;
//        if(StringUtils.containsIgnoreCase(url,"http://") || StringUtils.containsIgnoreCase(url,"https://")){
//            URI uri = URI.create(url);
//            ports = uri.getPort();
//            String path = uri.getPath();
//            System.out.println(path);
//            scheme = uri.getScheme();
//            if("http".equals(scheme)){
//                if (ports < 0) {
//                    ports = 80;
//                }
//                servicePorts = 80;
//            }else if("https".equals(scheme)){
//                if (ports < 0) {
//                    ports = 443;
//                }
//                servicePorts = 443;
//            }
//            targetUrl = uri.getHost()+":"+ports;
//            System.out.println("网络协议："+scheme+"\nIP:："+uri.getHost()+"\n端口号："+ports+"\n服务端口号："+servicePorts);
//            System.out.println(String.format("发布target地址：%s，服务协议：%s以及端口号：%s",targetUrl,scheme,servicePorts));
//        }else{
//            System.out.println("无效IP");
//        }
        try {
            setException();
        }catch (Exception ex){
            System.out.println(ex.toString());
        }
        String result = "{\"code\":\"10001\",\"data\":{\"datasource\":{\"datasourceName\":\"apic\",\"supplierId\":1,\"supplierName\":\"IT\"},\"id\":\"168f97368a264e878dd8a18cdf1a5aff\",\"responseParams\":{\"total\":8,\"data\":[{\"admin_auth\":\"apikey\",\"service_domain\":\"http://10.0.49.13:7850\",\"module\":\"\",\"net_work\":\"内网\",\"project\":\"api-at\",\"development_center\":\"安亭\",\"kafka_topic\":\"\",\"kafka_addr\":\"\",\"admin_url\":\"http://10.0.49.145:8001\",\"component_group\":\"\",\"component_type\":\"\",\"environment\":\"测试\",\"admin_apikey\":\"QwX1dcbyzHz6s\",\"attribute\":\"上汽\",\"id\":1,\"net_domain\":\"10.0.49.13:7850\",\"net_department\":\"信息系统\",\"ip_restriction\":\"\"}],\"message\":\"请求成功\",\"statusCode\":\"10001\"},\"statusType\":\"业务成功\"},\"message\":\"请求成功\"}";
        JSONObject resultObject = JSONObject.parseObject(result);
        JSONObject data = resultObject.getJSONObject("data");
        Optional<JSONObject> jsonObject = Optional.ofNullable(data);
        if(!jsonObject.isPresent()){
            throw new ErrorException(500,"获取研发中心配置失败");
        }
        JSONObject responseParams = data.getJSONObject("responseParams");
        List<JSONObject> domains = responseParams.getObject("data", List.class);
        domains.stream().filter(Objects::nonNull).forEach(o -> {
            Domain domain = o.toJavaObject(Domain.class);
            System.out.println(domain);
        });
    }

    private static void trstMethod() {
        String weekDate="";
        Calendar calendarNow = Calendar.getInstance();
        int week = calendarNow.get(Calendar.DAY_OF_WEEK)-1;
        switch(week) {
            case 0:
                weekDate="星期日";
                break;
            case 1:
                weekDate="星期一";
                break;
            case 2:
                weekDate="星期二";
                break;
            case 3:
                weekDate="星期三";
                break;
            case 4:
                weekDate="星期四";
                break;
            case 5:
                weekDate="星期五";
                break;
            case 6:
                weekDate="星期六";
                break;
        }
        System.out.println("今天是 "+weekDate);
        System.out.println("请输入您的出生年月（如 0123 表示 1 月 23 日）：");
        Scanner sc=new Scanner(System.in);
        int monthday=sc.nextInt();
        System.out.println(String.format("%04d",monthday));
        int month=monthday/100;
        int day=monthday%100;
        String xingzuo="";
        switch (month){
            case 1:
                    xingzuo=day<21?"摩羯座":"水瓶座";
                    break;
            case 2:
                    xingzuo=day<20? "水瓶座":"双鱼座";
                    break;
            case 3:
                    xingzuo=day<21?"双鱼座":"白羊座";
                    break;
            case 4:
                    xingzuo=day<21?"白羊座":"金牛座";
                    break;
            case 5:
                    xingzuo=day<22?"金牛座":"双子座";
                    break;
            case 6:
                    xingzuo=day<22?"双子座":"巨蟹座";
                    break;
            case 7:
                    xingzuo=day<23?"巨蟹座":"狮子座";
                    break;
            case 8:
                    xingzuo=day<24?"狮子座":"处女座";
                    break;
            case 9:
                    xingzuo=day<24?"处女座":"天秤座";
                    break;
            case 10:
                    xingzuo=day<24?"天秤座":"天蝎座";
                    break;
            case 11:
                    xingzuo=day<23?"天蝎座":"射手座";
                    break;
            case 12:
                    xingzuo=day<22?"射手座":"摩羯座";
                    break;
        }
        System.out.println("您的星座是：" +xingzuo);
        System.out.println("乘法口诀表：");
        for(int i=1;i<=9;i++){
            for(int j=1;j<=i;j++){
                System.out.print(j+"*"+i+"="+j*i+"\t");
            }
            System.out.println();
        }
        Scanner scan=new Scanner(System.in);
        System.out.println("打印杨辉三角形的行数：");
        int row=scan.nextInt();
        calculate(row);
        int[] no=new int[]{501,101,204,102,334};    //定义学号数组
        String[] names=new String[]{"张城","刘丽丽","李国旺","孟红霞","贺宁"};    //定义姓名数组
        String[] classes=new String[]{"数学","语文","数学","英语","英语"};    //定义课程数组
        System.out.println("本次考试学生信息如下：");
        //循环遍历数组，连接字符串
        for(int i=0;i<no.length;i++) {
            System.out.println("学号："+no[i]+"|姓名："+names[i]+"|课程："+classes[i]+"|班级："+"初二（三）班");
        }
        //验证手机
        validatePhone(scan);
        //验证IP
        validateIp();

    }

    private static void validateIp() {
        String regex="\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}";
        String answer="Y";
        do {
            System.out.print("请输入 IP 地址：");
            Scanner scan=new Scanner(System.in);
            String phone=scan.next();    //接收用户在控制台输入的电话号码
            Pattern pattern=Pattern.compile(regex);    //编译正则表达式
            Matcher matcher=pattern.matcher(phone);    //创建给定输入模式的匹配器
            boolean bool=matcher.matches();
            if(bool) {   //如果验证通过
                System.out.println("输入的 IP 地址正确。");
            } else {
                System.out.println("输入的IP地址格式错误。");
            }
            System.out.print("是否继续输入？（Y/N 或者 y/n)");
            answer=scan.next();
        }while(answer.equalsIgnoreCase("Y"));
        System.out.println("程序结束。");
    }

    private static void validatePhone(Scanner scan) {
        String regex="0\\d{2,3}[-]?\\d{7,8}|0\\d{2,3}\\s?\\d{7,8}|13[0-9]\\d{8}|15[1089]\\d{8}";
        String answer="Y";
        do {
            System.out.print("请留下您的电话号码：");
            Scanner scans = new Scanner(System.in);
            String phone = scans.next();    //接收用户在控制台输入的电话号码
            Pattern pattern = Pattern.compile(regex);    //编译正则表达式
            Matcher matcher = pattern.matcher(phone);    //创建给定输入模式的匹配器
            boolean bool=matcher.matches();
            if(bool) { //如果验证通过
                System.out.println("输入的电话号码格式正确。");
            } else {
                System.out.println("输入的电话号码无效，格式不正确。");
            }
            System.out.print("是否继续输入？（Y/N 或者 y/n）");
            answer=scan.next();
        }while(answer.equalsIgnoreCase("Y"));
        System.out.println("注册结束。");
    }

    //杨辉三角
    public static void calculate(int row)
    {
        for(int i=1;i<=row;i++)
        {
            for(int j=1;j<=row-i;j++)
            {
                System.out.print(" ");
            }
            for(int j=1;j<=i;j++)
            {   //打印空格后面的字符, 从第1 列开始往后打印
                System.out.print(num(i,j) +" ");
            }
            System.out.println();
        }
    }

    public static int num(int x,int y)
    {
        if(y==1||y==x)
        {
            return 1;
        }
        int c=num(x-1,y-1)+num(x-1,y);
        return c;
    }

    public static Integer getRemainSecondsOneDay(Date currentDate) {
        Calendar midnight=Calendar.getInstance();
        midnight.setTime(currentDate);
        midnight.add(midnight.DAY_OF_MONTH,1);//将日加1
        midnight.set(midnight.HOUR_OF_DAY,0);//控制时
        midnight.set(midnight.MINUTE,0);//控制分
        midnight.set(midnight.SECOND,0);//控制秒
        midnight.set(midnight.MILLISECOND,0);//毫秒
        //通过以上操作就得到了一个currentDate明天的0时0分0秒的Calendar对象，然后相减即可得到到明天0时0点0分0秒的时间差
        Integer seconds=(int)((midnight.getTime().getTime()-currentDate.getTime())/1000);
        return seconds;
    }

    public static Integer getRemainSecondsOneDays(Date currentDate) {
        //使用plusDays加传入的时间加1天，将时分秒设置成0
        LocalDateTime midnight = LocalDateTime.ofInstant(currentDate.toInstant(),
                ZoneId.systemDefault()).plusDays(1).withHour(0).withMinute(0)
                .withSecond(0).withNano(0);
        LocalDateTime currentDateTime = LocalDateTime.ofInstant(currentDate.toInstant(),
                ZoneId.systemDefault());
        //使用ChronoUnit.SECONDS.between方法，传入两个LocalDateTime对象即可得到相差的秒数
        long seconds = ChronoUnit.SECONDS.between(currentDateTime, midnight);
        return (int) seconds;
    }

    /**
     * 将Object对象转byte数组
     * @param obj byte数组的object对象
     * @return
     */
    public static byte[] toByteArray(Object obj) {
        byte[] bytes = null;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try {
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(obj);
            oos.flush();
            bytes = bos.toByteArray ();
            oos.close();
            bos.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        return bytes;
    }

    /**
     * 将byte数组转Object对象
     * @param bytes
     * @return
     */
    public static Object toObjectType(byte [] bytes){
        ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
        Object object = null;
        ObjectInputStream ois = null;
        try {
            ois = new ObjectInputStream(bis);
            object = ois.readObject();
            ois.close();
            bis.close();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return object;
    }


    /**
     * 生签
     **/
    public static String createSignature(String secretKey, Map<String, Object> parameters, Long timestamp) {
        StringBuilder assemble = assembleParameters(parameters);
        assemble.append(timestamp).append(";").append(secretKey);
        String encrypt = MD5Util.md5Encode(assemble.toString());
        return encrypt;
    }

    /**
     * 验签
     **/
    public static boolean checkSignature(String secretKey, Map<String, Object> parameters, Long timestamp,
                                  String signature) {
        if (StringUtils.isBlank(secretKey) || StringUtils.isBlank(signature) || timestamp == null) {
            return false;
        }
        StringBuilder assemble = assembleParameters(parameters);
        assemble.append(timestamp).append(";").append(secretKey);
        String encrypt = MD5Util.md5Encode(assemble.toString());
        return encrypt.equals(signature);
    }

    /**
     * 校验时间戳在时间区间内
     */
    public static boolean checkTimeStampInPeriod(long timestamp) {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.MINUTE, -15);
        long before = cal.getTime().getTime();
        Calendar cal2 = Calendar.getInstance();
        cal2.add(Calendar.MINUTE, 15);
        long after = cal2.getTime().getTime();
        return (before <= timestamp) && (timestamp <= after);
    }

    //组装服务参数
    public static <T> StringBuilder assembleParameters(Map<String, T> paramMap) {
        StringBuilder result = new StringBuilder();
        if (paramMap == null || paramMap.isEmpty()) {
            return result;

        }
        paramMap.entrySet().stream().sorted(Comparator.comparing(Map.Entry::getKey)).forEach(entry ->
                result.append(entry.getKey()).append(":").append(entry.getValue()).append(":"));
        return result;
    }


    public static void setException(){
        try {
            User user = null;
            user.getCountSum();
        }catch (Exception ex){
            throw new DataSourceException("asfq");
        }
    }
    private static void initIpAandNet(){
        Boolean flage = true;
        if(flage){
            String url = "api-serv.com:32";
            String[] strings = url.split(":");
            int port = 80;
            if(null!=strings && strings.length> 1){
                port = Integer.parseInt(strings[1]);
            }
            System.out.println("IP:："+strings[0]+"\n端口号："+port);
        }else{
            String urls = "https://10.0.40.122:12";
            if(StringUtils.containsIgnoreCase(urls,"http://") || StringUtils.containsIgnoreCase(urls,"https://")){
                URI uri = URI.create(urls);
                int ports = uri.getPort();
                if("http".equals(uri.getScheme())){
                    if (ports < 0) {
                        ports = 80;
                    }
                }else if("https".equals(uri.getScheme())){
                    if (ports < 0) {
                        ports = 443;
                    }
                }
                System.out.println("网络协议："+uri.getScheme()+"\nIP:："+uri.getHost()+"\n端口号："+ports);
            }else{
                System.out.println("无效IP");
            }
        }
    }

}
